﻿using System;
using System.IO;

namespace FileDuplicateRemover.Core
{
    public class EntityTreeBuilder : IDisposable
    {
        private string RootPath { get; set; }

        private int _CurrentCount;

        public EntityTreeBuilder(string rootPath)
        {
            this.RootPath = rootPath;
        }

        public DirectoryEntity Create(Func<int, bool> notify)
        {            
            DirectoryEntity de = new DirectoryEntity(RootPath);

            _CurrentCount = 0;
            CreateCore(de, notify);

            return de;
        }

        private void CreateCore(DirectoryEntity rootDirectoryEntity, Func<int, bool> notify)
        {
            foreach (string fullFileName in Directory.EnumerateFiles(rootDirectoryEntity.FullName))
            {
                FileEntity fe = new FileEntity(fullFileName);

                Add(rootDirectoryEntity, fe);

                _CurrentCount++;

                bool res = notify(_CurrentCount);

                if (res)
                    return;
            }

            foreach (string fullDirectoryName in Directory.EnumerateDirectories(rootDirectoryEntity.FullName))
            {
                DirectoryEntity de = new DirectoryEntity(fullDirectoryName);

                CreateCore(de, notify);

                Add(rootDirectoryEntity, de);

                _CurrentCount++;

                bool res = notify(_CurrentCount);

                if (res)
                    return;
            }
        }

        protected virtual void AddCore(DirectoryEntity directoryEntity, BaseEntity e)
        {
            directoryEntity.EntityList.Add(e);
            directoryEntity.TotalLength += e.TotalLength;
        }

        protected virtual void Add(DirectoryEntity directoryEntity, FileEntity fe)
        {
            FileInfo fi = new FileInfo(fe.FullName);
            fe.TotalLength = fi.Length;

            AddCore(directoryEntity, fe);

            directoryEntity.TotalEntityCount++;
        }

        protected virtual void Add(DirectoryEntity directoryEntity, DirectoryEntity de)
        {
            AddCore(directoryEntity, de);

            directoryEntity.TotalEntityCount += de.TotalEntityCount;
        }

        public void Dispose()
        {
        }
    }
}
